package com.bestcem.xm.member.controller;

import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.member.controller.param.displayrange.CreateDisplayRangeRequest;
import com.bestcem.xm.member.controller.param.displayrange.UpdateDisplayRangeRequest;
import com.bestcem.xm.member.controller.vo.DisplayRangeVO;
import com.bestcem.xm.member.enums.DisplayRangeTypeEnum;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.grpc.service.param.displayrange.CreateDisplayRangeParam;
import com.bestcem.xm.member.grpc.service.param.displayrange.GetDisplayRangeParam;
import com.bestcem.xm.member.grpc.service.param.displayrange.UpdateDisplayRangeParam;
import com.bestcem.xm.member.service.DisplayRangeService;
import com.bestcem.xm.member.service.dto.DisplayRangeDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author dc.wang <dc.wang@idiaoyan.com>
 * @version V1.0
 * @description 联系人展示范围web controller
 * @date 2021/8/4
 */
@Slf4j
@RestController
@RequestMapping("member/v2/mdisplayranges")
public class DisplayRangeController {
    private final DisplayRangeService displayRangeService;

    @Autowired
    public DisplayRangeController(DisplayRangeService displayRangeService) {
        this.displayRangeService = displayRangeService;
    }

    @GetMapping(path = "/health")
    public String checkHealth() {
        return "success";
    }

    @GetMapping()
    public XmResultJson<Map<String, DisplayRangeVO>> getDisplayRange(@RequestParam(name = "mtype", required = false) Integer memberType,
                                                                     HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        GetDisplayRangeParam param = new GetDisplayRangeParam(orgId, memberTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.getDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("查询项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeVO data = this.convertFrom(result.getData());
        Map<String, DisplayRangeVO> voMap = new HashMap<>(1);
        voMap.put("id", data);
        return XmResultJson.success(voMap);
    }

    @PostMapping("/create")
    public XmResultJson<String> createDisplayRange(@RequestBody CreateDisplayRangeRequest request,
                                                       HttpServletRequest httpServletRequest) {

        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        CreateDisplayRangeParam param = this.convertFrom(request);
        param.setOrgId(orgId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.createDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PutMapping()
    public XmResultJson<String> updateDisplayRange(@RequestBody UpdateDisplayRangeRequest request,
                                                       HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberType());
        DisplayRangeTypeEnum displayRangeTypeEnum = DisplayRangeTypeEnum.getByIndex(request.getDisplayRangeType());
        UpdateDisplayRangeParam param = new UpdateDisplayRangeParam(orgId, memberTypeEnum, displayRangeTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.updateDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @GetMapping("/ind")
    public XmResultJson<Map<String, DisplayRangeVO>> getIndDisplayRange(@RequestParam(name = "mtype", required = false) Integer memberType,
                                                                         HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        GetDisplayRangeParam param = new GetDisplayRangeParam(orgId, memberTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.getDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("查询项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeVO data = this.convertFrom(result.getData());
        Map<String, DisplayRangeVO> voMap = new HashMap<>(1);
        voMap.put("id", data);
        return XmResultJson.success(voMap);
    }

    @GetMapping("/ins")
    public XmResultJson<Map<String, DisplayRangeVO>> getInsDisplayRange(@RequestParam(name = "mtype", required = false) Integer memberType,
                                                                            HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        GetDisplayRangeParam param = new GetDisplayRangeParam(orgId, memberTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.getDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("查询项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeVO data = this.convertFrom(result.getData());
        Map<String, DisplayRangeVO> voMap = new HashMap<>(1);
        voMap.put("id", data);
        return XmResultJson.success(voMap);
    }

    @GetMapping("/int")
    public XmResultJson<Map<String, DisplayRangeVO>> getIntDisplayRange(@RequestParam(name = "mtype", required = false) Integer memberType,
                                                                            HttpServletRequest request) {
        
        String orgId = SecurityContextHolder.getOrgId();
        
         String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        GetDisplayRangeParam param = new GetDisplayRangeParam(orgId, memberTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.getDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("查询项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeVO data = this.convertFrom(result.getData());
        Map<String, DisplayRangeVO> voMap = new HashMap<>(1);
        voMap.put("id", data);
        return XmResultJson.success(voMap);
    }

    @PostMapping("/ind/create")
    public XmResultJson<String> createIndDisplayRange(@RequestBody CreateDisplayRangeRequest request,
                                                       HttpServletRequest httpServletRequest) {

        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        CreateDisplayRangeParam param = this.convertFrom(request);
        param.setOrgId(orgId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.createDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PostMapping("/ins/create")
    public XmResultJson<String> createInsDisplayRange(@RequestBody CreateDisplayRangeRequest request,
                                                          HttpServletRequest httpServletRequest) {

        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        CreateDisplayRangeParam param = this.convertFrom(request);
        param.setOrgId(orgId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.createDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PostMapping("/int/create")
    public XmResultJson<String> createIntDisplayRange(@RequestBody CreateDisplayRangeRequest request,
                                                          HttpServletRequest httpServletRequest) {

        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        CreateDisplayRangeParam param = this.convertFrom(request);
        param.setOrgId(orgId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.createDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("创建项目异常：{},参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PutMapping("/ind")
    public XmResultJson<String> updateIndDisplayRange(@RequestBody UpdateDisplayRangeRequest request,
                                                       HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberType());
        DisplayRangeTypeEnum displayRangeTypeEnum = DisplayRangeTypeEnum.getByIndex(request.getDisplayRangeType());
        UpdateDisplayRangeParam param = new UpdateDisplayRangeParam(orgId, memberTypeEnum, displayRangeTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.updateDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PutMapping("/ins")
    public XmResultJson<String> updateInsDisplayRange(@RequestBody UpdateDisplayRangeRequest request,
                                                          HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberType());
        DisplayRangeTypeEnum displayRangeTypeEnum = DisplayRangeTypeEnum.getByIndex(request.getDisplayRangeType());
        UpdateDisplayRangeParam param = new UpdateDisplayRangeParam(orgId, memberTypeEnum, displayRangeTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.updateDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    @PutMapping("/int")
    public XmResultJson<String> updateIntDisplayRange(@RequestBody UpdateDisplayRangeRequest request,
                                                          HttpServletRequest httpServletRequest) {
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberType());
        DisplayRangeTypeEnum displayRangeTypeEnum = DisplayRangeTypeEnum.getByIndex(request.getDisplayRangeType());
        UpdateDisplayRangeParam param = new UpdateDisplayRangeParam(orgId, memberTypeEnum, displayRangeTypeEnum);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        ServiceResult<DisplayRangeDto> result = displayRangeService.updateDisplayRange(param);
        if (!result.isSuccess()) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }
        DisplayRangeDto displayRangeDto = result.getData();
        if (displayRangeDto == null || StringUtils.isEmpty(displayRangeDto.getId())) {
            log.error("更新项目异常：{}，参数：{}", result.getMsg(), param);
            return XmResultJson.fail(-1, result.getMsg());
        }

        return XmResultJson.success(displayRangeDto.getId());
    }

    private CreateDisplayRangeParam convertFrom(CreateDisplayRangeRequest request) {
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberType());
        DisplayRangeTypeEnum displayRangeTypeEnum = DisplayRangeTypeEnum.getByIndex(request.getMemberType());
        return new CreateDisplayRangeParam(request.getOrgId(), memberTypeEnum, displayRangeTypeEnum);
    }

    private DisplayRangeVO convertFrom(DisplayRangeDto displayRangeDto) {
        DisplayRangeVO res = new DisplayRangeVO();
        BeanUtils.copyProperties(displayRangeDto, res);
        return res;
    }
}
